<template>
  <div class="markdown-list">
    <div 
      v-for="(content, index) in contents"
      :key="index"
      class="markdown-item"
      v-html="renderMarkdown(content)"
    />
  </div>
</template>

<script setup lang="ts">
import { shallowRef, watchEffect } from 'vue'
import MarkdownIt from 'markdown-it'
import type { PluginSimple } from 'markdown-it'
import mkatex from '@traptitech/markdown-it-katex'
import DOMPurify from 'dompurify'
import { setupHighlight } from '../utils/markdown'

interface Props {
  contents: string[]
  enableKatex?: boolean
  enableHighlight?: boolean
}

const props = withDefaults(defineProps<Props>(), {
  contents: () => [],
  enableKatex: true,
  enableHighlight: true
})



const md = shallowRef<MarkdownIt>()
const renderCache = new Map<string, string>()

const initRenderer = () => {
  renderCache.clear() // 清空缓存
  md.value = new MarkdownIt({
    html: true,
    linkify: true,
    breaks: true,
    //highlight: props.enableHighlight ? setupHighlight : undefined
    highlight: props.enableHighlight ? setupHighlight : undefined
  })

  if (props.enableKatex) {
  md.value!.use(mkatex as PluginSimple, { 
    throwOnError: false,
    output: 'mathml', // 强制输出 MathML 格式避免 HTML 残留
    macros: {},       // 清空可能存在的宏定义
    strict: false     // 禁用严格模式
  })
}
}



/*const sanitizeHTML = (dirty: string): string => {
  return DOMPurify.sanitize(dirty, {
    ADD_TAGS: ['iframe'],
    ADD_ATTR: ['allow', 'allowfullscreen', 'frameborder', 'scrolling']
  })
}*/

const sanitizeHTML = (dirty: string): string => {
  return DOMPurify.sanitize(dirty, {
    ADD_TAGS: ['iframe', 'span', 'div'], // 添加新标签
    ADD_ATTR: ['allow', 'allowfullscreen', 'frameborder', 'scrolling', 'class'], // 允许class属性
    ALLOW_DATA_ATTR: true
  })
}

const renderMarkdown = (content: string): string => {
  if (!md.value) return ''
  
  if (renderCache.has(content)) {
    return renderCache.get(content)!
  }

  const unsafeHtml = md.value.render(content)
  const safeHtml = sanitizeHTML(unsafeHtml)
  renderCache.set(content, safeHtml)

  return safeHtml
}

watchEffect(() => {
  initRenderer()
})
</script>

<style scoped lang="scss">
@use '../style/markdown';
@use '../style/katex';

.markdown-list {
  display: grid;
  gap: 1.5rem;
}
</style>